準周期タイプ のデータをRで分析する時の一連の手順になります。
データは、時刻付きのデータです。
センサーのデータには、0と1を使ってデータの変わり目を示す変数が入っていることがありますが、これにはありません。
下記のサンプルコードは、変わり目の変数を作るところからなので、このデータの扱いができれば、他の場合にも応用できます。
Rによるデータ全体の可視化 にあるPlotlyを使った方法で、データを見ます。 1次データ の分析になります。
library(plotly) # パッケージの読み込み
setwd("C:/Rtest") # 作業用ディレクトリを変更
Data <- read.csv("Data.csv", header=T) # データを読み込み
Data$Index <-as.numeric(row.names(Data)) # 行番号を読み込み
plot_ly(Data, x=~Index, y=~Y, type = 'scatter', mode = 'lines') # 折れ線グラフを描く(X軸は行番号)
-->
まず、できるのが左のグラフで、細かい山がたくさんある様子がわかります。 拡大したのが右のグラフで、山と山の間に一定値の区間があることがわかります。 機械のデータだと、一定値の区間は、機械が止まっている場合になっていることが多いです。 また、ひとつの山の間に、機械が動いて加工をしています。
実際のセンサーのデータだと、機械の状態を表すデータは、機械から出力されていることもあるのですが、 ここではないので、作ります。 機械が止まっている時は、Yは0になっているようなので、それを使ってデータを作ります。
Data$X01 <- ifelse(Data$Y>0, 1, 0) # 0より大きければ1、それ以外は0にした変数を作る
周期が変わるごとに0からスタートして、周期内では1ずつ増えていく列(X02,X04)を作ります。
また、次の周期になるごとに1ずつ増える列(X03,X05)を作ります。
X02とX03は、0が1に変わったタイミングをスタートにしています。 1.5次データの分析には便利です。
X04とX05は、1が0に変わったタイミングをスタートにしています。 停止時(0の時)の影響が稼働時(1の時)に起きているのかを分析したい時は使います。
Data$X02 <-Data$X01 # 新しい列を作る
Data$X03 <-Data$X01 # 新しい列を作る
Data$X04 <-Data$X01 # 新しい列を作る
Data$X05 <-Data$X01 # 新しい列を作る
n <- nrow(Data) # データの列数を数える
Data[1,5] <- 0# 1行目は0にする
Data[1,6] <- 0# 1行目は0にする
Data[1,7] <- 0# 1行目は0にする
Data[1,8] <- 0# 1行目は0にする
for (i in 2:n) { # ループの始まり
if (Data[i-1,4] == 0 && Data[i,4] == 1) { # 条件分岐の始まり
Data[i,5] <- 0# 条件に当てはまる場合は0にする
Data[i,6] <- Data[i-1,6] +1 # 条件に当てはまる場合は1を足していく。
Data[i,7] <- Data[i-1,7] +1 # 条件に当てはまらない場合は1を足していく。
Data[i,8] <- Data[i-1,8] # 条件に当てはまらない場合は前の行と同じ値。
} else if (Data[i-1,4] == 1 && Data[i,4] == 0){# 条件分岐
Data[i,5] <- Data[i-1,5] +1 # 条件に当てはまらない場合は1を足していく。
Data[i,6] <- Data[i-1,6] # 条件に当てはまらない場合は前の行と同じ値。
Data[i,7] <- 0# 条件に当てはまる場合は0にする
Data[i,8] <- Data[i-1,8] +1 # 条件に当てはまる場合は1を足していく。
} else {# 条件分岐
Data[i,5] <- Data[i-1,5] +1 # 条件に当てはまらない場合は1を足していく。
Data[i,6] <- Data[i-1,6] # 条件に当てはまらない場合は前の行と同じ値。
Data[i,7] <- Data[i-1,7] +1 # 条件に当てはまらない場合は1を足していく。
Data[i,8] <- Data[i-1,8] # 条件に当てはまらない場合は前の行と同じ値。
} # if文の処理の終わり
} # ループの終わり
ここまでで
1.5次データ
になります。
下記のコードで、周期ごとで色分けしたグラフを作れます。
ggplot(Data, aes(x=X02,y=Y, colour=X03)) + geom_line() # 層別の折れ線グラフを描く
2次データ を作って分析していくことになります。 ここでは比較的汎用的で、一度は確認しておいた方が良いような特徴量の作り方になります。 メタ知識 を駆使した特徴量を作る時にも、応用できます。
library(dplyr)# パッケージの読み込み
Data21 <- Data[Data$X01 == "0",] # X01が0のデータのみを抽出
Data22 <- Data21 %>% group_by(X05) # 新しい列を作る
Data23 <- summarize(Data22, n_0 = n()) # 新しい列を作る
Data31 <- Data[Data$X01 == "1",] # X01が0のデータのみを抽出
Data32 <- Data31 %>% group_by(X05) # 新しい列を作る
Data33 <- summarize(Data32, n_1 = n(), Max_Y_1 = max(Y), Min_Y_1 = min(Y), Start_Time_1 = min(Time), End_Time_1 = max(Time)) # 新しい列を作る
Data4 <- merge(Data23, Data33, all=T) # データを合体する
変数名は下記になります。
n_0 : X01が0のデータの個数。このデータの場合は、1秒毎のデータなので、X01が0の時間(秒)の意味になる。
n_1 : X01が1のデータの個数。このデータの場合は、1秒毎のデータなので、X01が1の時間(秒)の意味になる。
Max_Y_1 : X01が1の時のYの最大値
Min_Y_1 : X01が1の時のYの最小値
n_0とMax_Y_1で散布図を描くと、きれいに一直線に並んでいます。
つまり、X01が0の時間が長いと、Yの最大値が高いことがわかります。
1次データや1.5次データを眺めているだけでは、こうした分析結果を出すのは難しいのですが、2次データにすると、簡単に出せます。
ggplot(Data4, aes(x=n_0, y=Max_Y_1)) + geom_point() # 散布図を描く
上の分析例の意味は、「機械が動いている時の最大値は、その直前に機械が止まっている時間に比例している」というものです。
機械の加工に異常があった時は、まず機械が動いてる時のデータに目が行きます。 例えば、加工に異常があった時は、Yのデータが高い時であることは、この見方で気づけます。
しかし、「なぜ、高い時があるのか?」は、機械が動いている時のデータをいくら見てもわかりません。
こんな時に、機械が止まっている時間の状況も調べると、原因究明のヒントになることがあります。 上記の例だと、機械が止まっている時間と、Yのデータの最大値には関係があることがヒントになる可能性があります。
このページのサンプルコードは、機械が止まっている時の情報も得られるように作っています。 このページの例では、機械が止まっている時は、Yは0で一定値なので、特に何もしていませんが、 機械が止まっている時のYの最大値や最小値を求めてみると良いこともあります。
工場のデータ分析では、2次データを作るところでは終わらず、品質や機械の状態のデータと紐付けて 3次データ を作らないと、やりたいことにつながらないです。
センサーデータの中に、紐付けに使えるIDのようなものがあれば楽なのですが、ない場合、 時刻のデータを見比べて、紐付けるしかありません。
プログラミングでスマートにできることは稀で、時には1個ずつ手で紐付ける作業が必要になることもあります。